iT邦幫忙

2022 iThome 鐵人賽

DAY 25
0

測試 React Router

今天來練習測試 React Router ,範例程式碼的部分針對 React Router 文件的介紹稍微修改後如下:

import * as React from "react";
import { Routes, Route, Link } from "react-router-dom";

const App = () => {

  const Home = () => (
    <>
      <main>
        <h2>Welcome to the home page!</h2>
      </main>
    </>
  );

  const About = () => (
    <>
      <main>
        <h2>Welcome to the about page!</h2>
      </main>
    </>
  );

  return (
    <div>
      <header>
        <h1>Welcome to React Router!</h1>
        <ul>
          <li>
            <Link to="/">Home</Link>
          </li>
          <li>
            <Link to="/about">About</Link>
          </li>
        </ul>
      </header>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="about" element={<About />} />
      </Routes>
    </div>
  );
};

export default App;

在 App 元件內有 Home 、 About 元件,點擊時可切換頁面:

圖片

開始測試

首先來釐清測試內容,在釐清時可以想像自己是使用者,當自己是使用者時希望網頁給自己怎樣的操作體驗 ?

如:希望能正確呈現頁面、希望點擊網頁連結時能正確換頁等。

測試內容

Router 要測試的主要部分包含:

  1. 一開始是否能正確顯示預設的 Home 頁面
  2. 點擊連結時是否能正確換頁

接下來會使用 MemoryRouter 來進行測試,底下是關於 MemoryRouter 的介紹:

MemoryRouter
A Router that keeps the history of your “URL” in memory (does not read or write to the address bar). Useful in tests and non-browser environments like React Native.

而使用方式有兩種,第一種方式如下:

方法一

第一種方式需下載 history library,history 套件為 React Router 主要依賴項之一,透過將 history 傳給 Router 使用:

  • history.location 代表現在位置
    • pathname 現在的網址路徑

使用 fireEvent.click 點擊相關連結後並透過 history.location.pathname 斷言現在 url 位置是否正確。

import React from "react";
import { Router } from "react-router-dom";
import { screen, render, fireEvent } from "@testing-library/react";
import "@testing-library/jest-dom/extend-expect";
import { createMemoryHistory } from "history";
import App from "./App";

describe("Method one", () => {
  test("The initial page is Home Page", () => {
    const history = createMemoryHistory();
    render(
      <Router location={history.location} navigator={history}>
        <App />
      </Router>
    );
    expect(history.location.pathname).toBe("/");
  });
  test("Click the link to jump to the page", () => {
    const history = createMemoryHistory();
    render(
      <Router location={history.location} navigator={history}>
        <App />
      </Router>
    );
    fireEvent.click(screen.getByText("About"));
    expect(history.location.pathname).toBe("/about");
    
    fireEvent.click(screen.getByText("Home"));
    expect(history.location.pathname).toBe("/");
  });
});

備註:navigator={history} 在 React Router v4、v5 版本時等於 history={history}

方法二

直接在 render 時使用 MemoryRouter 包覆 App 元件,並透過 initialEntries 陣列傳入初始頁面,底下為 initialEntries 詳細介紹:

initialEntries: array
An array of locations in the history stack. These may be full-blown location objects with { pathname, search, hash, state } or simple string URLs.

最後透過 Jest DOM 的 toBeInTheDocument 斷言點擊時是否有切換頁面成功:

import React from "react";
import { Router } from "react-router-dom";
import { screen, render, fireEvent } from "@testing-library/react";
import "@testing-library/jest-dom/extend-expect";
import { MemoryRouter } from "react-router-dom";
import App from "./App";

describe("Method two", () => {
  test("The initial page is Home Page", () => {
    render(
      <MemoryRouter initialEntries={["/"]}>
        <App />
      </MemoryRouter>
    );
    expect(screen.getByText("Home")).toBeInTheDocument();
  });
  test("Click the link to jump to the page", () => {
    render(
      <MemoryRouter initialEntries={["/"]}>
        <App />
      </MemoryRouter>
    );
    fireEvent.click(screen.getByText("About"));
    expect(screen.getByText("About")).toBeInTheDocument();

    fireEvent.click(screen.getByText("Home"));
    expect(screen.getByText("Home")).toBeInTheDocument();
  });
});

https://ithelp.ithome.com.tw/upload/images/20221010/20139066Q3lNn65luS.png

這樣就完成模擬路由的切換囉!


參考文章

https://testing-library.com/docs/example-react-router/
https://reactrouter.com/en/v6.3.0/getting-started/installation
https://www.gushiciku.cn/pl/ptd1/zh-tw
https://stackoverflow.com/questions/69859509/cannot-read-properties-of-undefined-reading-pathname-when-testing-pages-in
https://medium.com/enjoy-life-enjoy-coding/react-unit-test-react-的-route-單元測試-feat-jest-react-testing-library-e89b5c7e6d35


上一篇
Mock Service Worker 學習(三)
下一篇
Login 測試(一):元件渲染及 Input 操作流程
系列文
<< 測試魔法 >> 這能動嗎?不然就測測看好了!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言